package io.gitee.chearnee.fw.datasecurity.core.executor.desensitization;

import io.gitee.chearnee.fw.datasecurity.core.common.SDCacheUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Map;
import java.util.Set;

/**
 * @author cn
 * @version 1.0
 * @description
 * @date 11/10/2022 3:59 PM
 */
@Slf4j
public class BeanSDExecutor implements SDExecutor<Object> {

    @Override
    @SneakyThrows
    public Object execute(Object obj, Annotation anno, Set<Class<?>> disabledClasses) {
        if (obj == null) {
            return null;
        }
        SDCacheUtil.SDEntity sdEntity = SDCacheUtil.getBeanStringField(obj);
        if (sdEntity == null) {
            return obj;
        }
        ArrayList<Field> beanFields = sdEntity.getBeanFields();
        Map<Field, Annotation> stringFields = sdEntity.getStringFields();
        for (Field beanField : beanFields) {
            if (!beanField.isAccessible()) {
                beanField.setAccessible(true);
            }
            Object fieldValue = beanField.get(obj);
            Object sdValue = SDExecutorFactory.getSDExecutor(fieldValue).executeObject(fieldValue, null, disabledClasses);
            beanField.set(obj, sdValue);
        }
        for (Map.Entry<Field, Annotation> fieldAnnotationEntry : stringFields.entrySet()) {
            Field field = fieldAnnotationEntry.getKey();
            Annotation annotation = fieldAnnotationEntry.getValue();
            if (!field.isAccessible()) {
                field.setAccessible(true);
            }
            Object fieldValue = field.get(obj);
            //单独对BigDecimal特殊处理
            if (fieldValue instanceof Number) {
                continue;
            }
            Object sdValue = SDExecutorFactory.getSDExecutor(fieldValue).executeObject(fieldValue, annotation, disabledClasses);
            field.set(obj, sdValue);
        }
        return obj;
    }
}
